package com.kly.user.chatterService;

import com.alibaba.excel.util.StringUtils;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.exception.common.ApplicationException;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jsoniter.output.JsonStream;
import com.kly.user.db.dao.*;
import com.kly.user.db.entity.*;
import com.kly.user.dto.chatter.request.QueryModelReq;
import com.kly.user.dto.chatter.request.QueryNewModelReq;
import com.kly.user.dto.chatter.response.*;
import com.kly.user.dto.vo.UserModelVo;
import com.kly.user.enums.UserStatus;
import com.kly.user.utils.ImagePrefixUtils;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * model相关处理类
 */
@Service("modelService")
public class ModelServiceImpl implements ModelService {
    private static final Log logger = LogFactory.getLog(ModelServiceImpl.class);
    @Resource
    UserChatterMappingDao userChatterMappingDao;
    @Resource
    UserDao userDao;
    @Resource
    UserChatterCustomDao userChatterCustomDao;
    @Resource
    UserMsgUnreadNumDao userMsgUnreadNumDao;

    @Autowired
    private MsgModelUnreadDao msgModelUnreadDao;
    /**
     * 有效标记
     */
    private final static Integer EFFECTIVE_STATUS = 1;
    /**
     * 显示syaHiToAll按扭
     */
    private final static int SHOW_SAY_HI_TO_ALL = 1;
    /**
     * 隐藏syaHiToAll按扭
     */
    private final static int HIDE_SAY_HI_TO_ALL = 0;


    /**
     * 获取新关系列表
     */
    @Override
    public Response<NewModelsDto> queryNewModelList(QueryNewModelReq req) {
        if (Objects.isNull(req) || StringUtils.isBlank(req.getChatterUserCode())) {
            throw new ApplicationException("The parameter [chatterUserCode] should not be empty");
        }

        final UserEntity userEntity = queryByUserCode(req);
        if (Objects.isNull(userEntity)) {
            throw new ApplicationException("The account [" + req.getChatterUserCode() + "] does not exists in records");
        }

        final List<UserChatterEntity> userChatterEntities = userChatterCustomDao.queryNewMatchList(req.getChatterUserCode());
        if (CollectionUtils.isEmpty(userChatterEntities)) {
            return Response.ok();
        }
        // 显示syaHiToAll按扭
        int sayHiToAll = HIDE_SAY_HI_TO_ALL;
        List<NewModel> matchedList = Lists.newArrayList();
        for (UserChatterEntity o : userChatterEntities) {
            if (o.getShowSayHiFlag() == SHOW_SAY_HI_TO_ALL) {
                sayHiToAll = SHOW_SAY_HI_TO_ALL;
            }
            final UserAccount userAccount = UserAccount.builder().userCode(o.getUserCode()).gender(o.getGender()).avatarUrl(getImageUrl(o.getAvatarUrl())).nickName(o.getNickName()).online(o.getOnline()).build();
            final ModelAccount modelAccount = ModelAccount.builder().avatarUrl(getImageUrl(o.getModelAvatarUrl())).nickName(o.getModelNickName()).userCode(o.getModelUserCode()).gender(o.getModelGender()).showSayHiFlag(o.getShowSayHiFlag()).online(o.getOnline()).build();
            final NewModel newModel = NewModel.builder().contactTime(getContactTime(o.getGmtModified())).userAccount(userAccount).modelAccount(modelAccount).build();
            matchedList.add(newModel);
        }
        final NewModelsDto newModelsDto = NewModelsDto.builder().matchedList(matchedList).matchNum(userChatterEntities.size()).showSayHiToAllFlag(sayHiToAll).build();
        return Response.ok(newModelsDto);

    }

    /**
     * 获取model列表
     */
    @Override
    public Response<ModelsDto> queryModelList(QueryModelReq req) {
        final List<UserModelEntity> userModelEntities = userChatterCustomDao.queryModels(req.getChatterUserCode(), req.getModelUserCode());
        final Map<String, List<UnReadMsgDto>> unReadUsers = getUnReadUsers(userModelEntities);
        return queryModelListCommon(userModelEntities, unReadUsers);
    }

    @Override
    public Response<ChatterModelsUnreadMsgDto> getChatterModelsUnreadMsgInfo(String chatterUserCode) {
        logger.info("==getChatterModelsUnreadMsgInfo 请求model未读数量 开始==,chatterUserCode:{}", chatterUserCode);
        List<UserModelEntity> userModelEntities = userChatterCustomDao.queryModels(chatterUserCode, null);
        if (CollectionUtils.isEmpty(userModelEntities)) {
            logger.error("==getChatterModelsUnreadMsgInfo 该chatter没有绑定的model ==,chatterUserCode:{}", chatterUserCode);
            return Response.ok();
        }
        logger.info("==getChatterModelsUnreadMsgInfo 获取model数==,chatterUserCode:{},size:{}", chatterUserCode, userModelEntities.size());
        List<String> modelUserCodes = userModelEntities.parallelStream().map(UserModelEntity::getModelUserCode).collect(Collectors.toList());
        List<MsgModelUnreadEntity> listWithTotalUnreadMsgCntByModels = msgModelUnreadDao.getListWithTotalUnreadMsgCntByModels(modelUserCodes);
        logger.info("==getChatterModelsUnreadMsgInfo 查询到未读的消息记录数==,chatterUserCode:{},size:{}", chatterUserCode, userModelEntities.size());
        Map<String, Integer> modelWithUnreadTotal = new HashMap<>();
        listWithTotalUnreadMsgCntByModels.forEach(u -> {
            modelWithUnreadTotal.put(u.getModelCode(), u.getUnreadMsgNum());
        });

        List<UserModelVo> userModelVos = new ArrayList<>();
        userModelEntities.forEach(m -> {
            UserModelVo userModelVo = new UserModelVo().setModelUserCode(m.getModelUserCode()).setNickName(m.getModelNickName()).setToken(m.getToken()).setChatterUserCode(m.getChatterUserCode()).setModelAvatarUrl(getImageUrl(m.getModelAvatarUrl()));
            userModelVos.add(userModelVo);
        });

        logger.info("==getChatterModelsUnreadMsgInfo 请求model未读数量 结束==,chatterUserCode:{}", chatterUserCode);
        ChatterModelsUnreadMsgDto chatterModelsUnreadMsgDto = new ChatterModelsUnreadMsgDto(userModelVos, modelWithUnreadTotal);
        return Response.ok(chatterModelsUnreadMsgDto);
    }

    private Response<ModelsDto> queryModelListCommon(List<UserModelEntity> userModelEntities, Map<String, List<UnReadMsgDto>> unReadUsers) {
        if (CollectionUtils.isNotEmpty(userModelEntities)) {
            List<ChatUser> modelList = Lists.newArrayList();
            userModelEntities.forEach(o -> {
                final UserAccount userAccount = UserAccount.builder().build();
                BeanUtils.copyProperties(o, userAccount);

                final ModelAccount modelAccount = ModelAccount.builder().build();
                modelAccount.setUserCode(o.getModelUserCode());
                modelAccount.setNickName(o.getModelNickName());
                modelAccount.setAvatarUrl(getImageUrl(o.getModelAvatarUrl()));
                modelAccount.setToken(o.getToken());
                modelAccount.setUnReadNum(o.getUnReadNum());
                modelAccount.setTargetId(o.getTargetId());
                modelAccount.setUnreadDetail(unReadUsers.get(o.getModelUserCode()));
                final ChatUser chatUser = ChatUser.builder().userAccount(userAccount).modelAccount(modelAccount).build();
                modelList.add(chatUser);

            });

            int totalUnReadNum = userModelEntities.stream().mapToInt(UserModelEntity::getUnReadNum).sum();
            final ModelsDto modelDto = ModelsDto.builder().matchTotalNum(userModelEntities.size()).modelList(modelList).totalUnReadNum(totalUnReadNum).build();
            return Response.ok(modelDto);
        }

        return Response.ok();
    }

    private Map<String, List<UnReadMsgDto>> getUnReadUsers(List<UserModelEntity> userModelEntities) {
        if (CollectionUtils.isEmpty(userModelEntities)) {
            return Maps.newHashMap();
        }
        final List<String> modelCodes = userModelEntities.parallelStream().map(UserModelEntity::getModelUserCode).collect(Collectors.toList());
        final List<UserMsgUnreadNumEntity> userMsgUnreadNumEntities = userMsgUnreadNumDao.listModelUnreadReadMsgNum(modelCodes);
        if (CollectionUtils.isEmpty(userMsgUnreadNumEntities)) {
            return Maps.newHashMap();
        }
        Map<String, List<UnReadMsgDto>> retMap = Maps.newHashMap();
        for (String modelCode : modelCodes) {
            final List<UserMsgUnreadNumEntity> groupByModelCode = userMsgUnreadNumEntities.parallelStream().filter(o -> o.getUnreadNum() > 0 && modelCode.equals(o.getToUserCode())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(groupByModelCode)) {
                retMap.put(modelCode, groupByModelCode.parallelStream().map(o -> UnReadMsgDto.builder().userCode(o.getFromUserCode()).unReadNum(o.getUnreadNum()).build()).collect(Collectors.toList()));
            }
        }
        return retMap;
    }

    @Override
    public Response<ModelsProfileDto> queryModelDetails(String chatterUserCode) {
        if (StringUtils.isBlank(chatterUserCode)) {
            return Response.ok();
        }

        final List<UserChatterMappingEntity> userChatterMappingEntities = userChatterMappingDao.queryByChatterUserCode(chatterUserCode);
        if (CollectionUtils.isEmpty(userChatterMappingEntities)) {
            return Response.ok();
        }
        final List<ModelProfile> modelList = userChatterMappingEntities.stream().map(o -> {
            return ModelProfile.builder().avatarUrl(getImageUrl(o.getModelAvatarUrl())).nickName(o.getModelNickName()).userCode(o.getModelUserCode()).gender(o.getModelGender()).build();
        }).collect(Collectors.toList());

        final ModelsProfileDto modelsProfileDto = ModelsProfileDto.builder().modelAccount(modelList).build();
        return Response.ok(modelsProfileDto);
    }

    private String getContactTime(Date date) {
        if (Objects.isNull(date)) {
            return Strings.EMPTY;
        }
//        String day = String.format(Locale.US, "%td", date);
//        String month = String.format(Locale.US, "%tb", date);
//        if (DateUtil.isSameDay(date, DateUtil.date())){
//            return DateUtil.format(date,"HH:mm");
//        }
//        return month + " " + day;

        return String.valueOf(date.getTime());
    }


    /**
     * 获取用户信息
     */
    private UserEntity queryByUserCode(QueryNewModelReq req) {
        Map<String, Object> params = Maps.newHashMap();
        params.put("userCode", req.getChatterUserCode());
        params.put("deleted", 0);
        params.put("status", UserStatus.ACTIVE.getType());
        final List<UserEntity> userEntities = Optional.ofNullable(userDao.selectByParams(params)).orElse(Lists.newArrayList());
        if (CollectionUtils.isEmpty(userEntities)) {
            return null;
        }
        return userEntities.get(0);
    }

    private String getImageUrl(String url) {
        return ImagePrefixUtils.getFullImageUrl(url);
    }


}
